﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Collections;
using System.Diagnostics;
using System.Threading;

using log4net; 

using NetworkAssetManager.General;
using ExtendedListView.Forms;
using System.Reflection;
using NetworkAssetManager.Entity;
using System.Text.RegularExpressions;

namespace NetworkAssetManager.Forms
{
    public partial class MainUI : Form
    {
        Process dbgProcess = null;
        BackgroundWorker worker = new BackgroundWorker();
        Hashtable objDataTable = new Hashtable(); 
        int iLstUnSelect = -1;
        private static readonly ILog _logger = LogManager.GetLogger(typeof(MainUI));

        public MainUI()
        {
            InitializeComponent();

            Hashtable.Synchronized(objDataTable); 
            _logger.Info("Registering callbacks for UI update");

            NetworkAssetManager.DataAcccess.CreateDatabase.VerifyDatabaseExists();
            Controller.Instance.MachineFound += new Controller.DelegateMachineFound(Instance_MachineFound);
            Controller.Instance.MachineDiscoveryStart += new Controller.DelegateMachineDiscoveryStart(Instance_MachineDiscoveryStart);
            Controller.Instance.MachineDiscoveryComplete += new Controller.DelegateMachineDiscoveryComplete(Instance_MachineDiscoveryComplete);
            Controller.Instance.StatusMessage += new Controller.DelegateStatusMessage(Instance_StatusMessage);
            Controller.Instance.ScanComplete += new Controller.DelegateScanComplete(Instance_ScanComplete);
           
//TODO_HIGH: Improve the threading logic
 
            worker.DoWork += new DoWorkEventHandler(worker_collectWmiData);
            worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(worker_collectWmiDataComplete);
        }

        void DisplaySystemDetails()
        {
            _logger.Info("Displaying system details");

            
            if (objDataTable == null || objDataTable["System"] == null)
            {
                SetProgressBarState(false);
                return;
            }

            ArrayList tempArray = (ArrayList)objDataTable["System"]; 
 
            if ( tempArray.Count <= 0)
            {
                SetProgressBarState(false);
                return;
            }

            TreeListNode mainParentNode = null;

            foreach (object entity in tempArray)
            {

                bool bNodeAlreadyAdded = true;
                string _name = SplitCamelCase(entity.GetType().GetProperty("ClassName")
                    .GetValue(entity, null).ToString());


                int imageIndex = (int)entity.GetType().GetProperty("Icon").GetValue(entity, null);

                foreach (TreeListNode tempParentNode in lstDisplayInfo.Nodes)
                {
                    if (tempParentNode.Text == _name)
                    {
                        mainParentNode = tempParentNode;
                        bNodeAlreadyAdded = false;
                        break;
                    }
                }

                if (mainParentNode == null)
                {
                    mainParentNode = new TreeListNode();
                    mainParentNode.Text = _name;
                    mainParentNode.ImageIndex = imageIndex;
                    bNodeAlreadyAdded = true;
                }

                TreeListNode tln = new TreeListNode();
                tln.Text = entity.GetType().GetProperty("NodeName")
                    .GetValue(entity, null).ToString();
                tln.ImageIndex = imageIndex;

                Type t = entity.GetType();
                PropertyInfo[] pi = t.GetProperties();

                foreach (PropertyInfo prop in pi)
                {
                    if (prop.Name == "ClassName" || prop.Name == "ScanID" 
                        || prop.Name == "Icon" || prop.Name == "NodeName")
                        continue;

                    TreeListNode sub = new TreeListNode();
                    sub.Text = SplitCamelCase(prop.Name);

                    if (prop.GetValue(entity, null).GetType().Name == "DateTime" && DateTime.MinValue == (DateTime)prop.GetValue(entity, null))
                        sub.SubItems.Add("");
                    else
                        sub.SubItems.Add(prop.GetValue(entity, null).ToString());

                    sub.ImageIndex = -1;
                    tln.Nodes.Add(sub);
                    sub = null;
                    //MessageBox.Show("Prop: " + prop.GetValue(entity, null).ToString());
                }

                mainParentNode.Nodes.Add(tln);

                tln = null;

                if (bNodeAlreadyAdded == true)
                    lstDisplayInfo.Nodes.Add(mainParentNode);

                mainParentNode = null;
                
            }
            if (cbListExpand.Checked == true)
                lstDisplayInfo.ExpandAll();

            lstDisplayInfo.Invalidate();
            SetProgressBarState(false);
            tempArray.Clear();
            tempArray = null; 

        }

//TODO_HIGH: Improve the logic for displaying the processes
        void DisplayProcessesDetails()
        {
            _logger.Info("Displaying process details");


            if (objDataTable == null || objDataTable["Processes"] == null)
            {
                SetProgressBarState(false);
                return;
            }

            ArrayList tempArray = (ArrayList)objDataTable["Processes"];

            if (tempArray.Count <= 0)
            {
                SetProgressBarState(false);
                return;
            }

            bool bCreateColumns = true; 

            if (lstProcesses.Columns.Count != 0)
            {
                bCreateColumns = false;
            }

            foreach (object entity in tempArray)
            {
                string _name = SplitCamelCase(entity.GetType().GetProperty("ClassName")
                    .GetValue(entity, null).ToString());

                ListViewItem listItem = new ListViewItem();

                listItem.Text = entity.GetType().GetProperty("Name")
                    .GetValue(entity, null).ToString();
                listItem.ImageIndex = 0;


                if (bCreateColumns == true)
                    lstProcesses.Columns.Add("Name", 100, HorizontalAlignment.Left);

                Type t = entity.GetType();
                PropertyInfo[] pi = t.GetProperties();

                foreach (PropertyInfo prop in pi)
                {
                    if (prop.Name == "ClassName" || prop.Name == "ScanID" || prop.Name == "Name" || prop.Name == "Icon" || prop.Name == "NodeName")
                        continue;

                    if (prop.GetValue(entity, null).GetType().Name == "DateTime" && DateTime.MinValue == (DateTime)prop.GetValue(entity, null))
                        listItem.SubItems.Add("");
                    else
                        listItem.SubItems.Add(prop.GetValue(entity, null).ToString());

                    if (bCreateColumns == true)
                        lstProcesses.Columns.Add(prop.Name , 100, HorizontalAlignment.Left);
                }
                lstProcesses.Items.Add(listItem);
                bCreateColumns = false; 
            }
            lstProcesses.Columns[0].Width = -1;

            tempArray.Clear();
            tempArray = null; 
        }
        void DisplaySoftwareDetails()
        {
            _logger.Info("Displaying installed software details");

            if (objDataTable == null || objDataTable["Softwares"] == null)
            {
                SetProgressBarState(false);
                return;
            }

            ArrayList tempArray = (ArrayList)objDataTable["Softwares"];

            if (tempArray.Count <= 0)
            {
                SetProgressBarState(false);
                return;
            }

            bool bCreateColumns = true;

            if (lstSoftwares.Columns.Count != 0)
            {
                bCreateColumns = false;
            }

            foreach (object entity in tempArray)
            {
                string _name = SplitCamelCase(entity.GetType().GetProperty("ClassName")
                    .GetValue(entity, null).ToString());

                ListViewItem listItem = new ListViewItem();

                listItem.Text = entity.GetType().GetProperty("Name")
                    .GetValue(entity, null).ToString();
                listItem.ImageIndex = 0;

                if (bCreateColumns == true)
                    lstSoftwares.Columns.Add("Name", 100, HorizontalAlignment.Left);

                Type t = entity.GetType();
                PropertyInfo[] pi = t.GetProperties();

                foreach (PropertyInfo prop in pi)
                {
                    if (prop.Name == "ClassName" || prop.Name == "ScanID" || prop.Name == "Name" || prop.Name == "Icon" || prop.Name == "NodeName")
                        continue;

                    if (prop.GetValue(entity, null).GetType().Name == "DateTime" && DateTime.MinValue == (DateTime)prop.GetValue(entity, null))
                        listItem.SubItems.Add("");
                    else
                        listItem.SubItems.Add(prop.GetValue(entity, null).ToString());


                    if (bCreateColumns == true)
                        lstSoftwares.Columns.Add(prop.Name, 100, HorizontalAlignment.Left);
                }
                lstSoftwares.Items.Add(listItem);
                bCreateColumns = false;
            }
            lstSoftwares.Columns[0].Width = -1;

            tempArray.Clear();
            tempArray = null; 
        }
        void DisplayServicesDetails()
        {
            _logger.Info("Displaying services details");

            if (objDataTable == null || objDataTable["Services"] == null)
            {
                SetProgressBarState(false);
                return;
            }

            ArrayList tempArray = (ArrayList)objDataTable["Services"];

            if (tempArray.Count <= 0)
            {
                SetProgressBarState(false);
                return;
            }


            bool bCreateColumns = true;

            if (lstServices.Columns.Count != 0)
            {
                bCreateColumns = false;
            }

            foreach (object entity in tempArray)
            {
                string _name = SplitCamelCase(entity.GetType().GetProperty("ClassName")
                    .GetValue(entity, null).ToString());


                ListViewItem listItem = new ListViewItem();

                listItem.Text = entity.GetType().GetProperty("DisplayName")
                    .GetValue(entity, null).ToString();
                listItem.ImageIndex = 0;

                if (bCreateColumns == true)
                    lstServices.Columns.Add("Name", 100, HorizontalAlignment.Left);

                Type t = entity.GetType();
                PropertyInfo[] pi = t.GetProperties();

                foreach (PropertyInfo prop in pi)
                {
                    if (prop.Name == "ClassName" || prop.Name == "ScanID" || prop.Name == "DisplayName" || prop.Name == "Icon" || prop.Name == "NodeName")
                        continue;

                    if (prop.GetValue(entity, null).GetType().Name == "DateTime" && DateTime.MinValue == (DateTime)prop.GetValue(entity, null))
                        listItem.SubItems.Add("");
                    else
                        listItem.SubItems.Add(prop.GetValue(entity, null).ToString());

                    if (bCreateColumns == true)
                        lstServices.Columns.Add(prop.Name, 100, HorizontalAlignment.Left);
                }
                lstServices.Items.Add(listItem);
                bCreateColumns = false;
            }
            lstServices.Columns[0].Width = -1;

            tempArray.Clear();
            tempArray = null; 
        }

        void DisplayIPRoutesDetails()
        {
            _logger.Info("Displaying IPRoutes details");

            if (objDataTable == null || objDataTable["IPRoutes"] == null)
            {
                SetProgressBarState(false);
                return;
            }

            ArrayList tempArray = (ArrayList)objDataTable["IPRoutes"];

            if (tempArray.Count <= 0)
            {
                SetProgressBarState(false);
                return;
            }


            bool bCreateColumns = true;

            if (lstIPRoutes.Columns.Count != 0)
            {
                bCreateColumns = false;
            }

            foreach (object entity in tempArray)
            {
                string _name = SplitCamelCase(entity.GetType().GetProperty("ClassName")
                    .GetValue(entity, null).ToString());


                ListViewItem listItem = new ListViewItem();

                listItem.Text = entity.GetType().GetProperty("Name")
                    .GetValue(entity, null).ToString();
                listItem.ImageIndex = 0;

                if (bCreateColumns == true)
                    lstIPRoutes.Columns.Add("Name", 100, HorizontalAlignment.Left);

                Type t = entity.GetType();
                PropertyInfo[] pi = t.GetProperties();

                foreach (PropertyInfo prop in pi)
                {
                    if (prop.Name == "ClassName" || prop.Name == "ScanID" || prop.Name == "Name" || prop.Name == "Icon" || prop.Name == "NodeName")
                        continue;

                    if (prop.GetValue(entity, null).GetType().Name == "DateTime" && DateTime.MinValue == (DateTime)prop.GetValue(entity, null))
                        listItem.SubItems.Add("");
                    else
                        listItem.SubItems.Add(prop.GetValue(entity, null).ToString());

                    if (bCreateColumns == true)
                        lstIPRoutes.Columns.Add(prop.Name, 100, HorizontalAlignment.Left);
                }
                lstIPRoutes.Items.Add(listItem);
                bCreateColumns = false;
            }
            lstIPRoutes.Columns[0].Width = -1;

            tempArray.Clear();
            tempArray = null;
        }

        void DisplayEnvVarDetails()
        {
            _logger.Info("Displaying Environment variable details");

            if (objDataTable == null || objDataTable["EnvVars"] == null)
            {
                SetProgressBarState(false);
                return;
            }

            ArrayList tempArray = (ArrayList)objDataTable["EnvVars"];

            if (tempArray.Count <= 0)
            {
                SetProgressBarState(false);
                return;
            }


            bool bCreateColumns = true;

            if (lstEnvVars.Columns.Count != 0)
            {
                bCreateColumns = false;
            }

            foreach (object entity in tempArray)
            {
/*
                string _name = SplitCamelCase(entity.GetType().GetProperty("ClassName")
                    .GetValue(entity, null).ToString());
*/


                ListViewItem listItem = new ListViewItem();

                listItem.Text = entity.GetType().GetProperty("Name")
                    .GetValue(entity, null).ToString();
                listItem.ImageIndex = 0;

                if (bCreateColumns == true)
                    lstEnvVars.Columns.Add("Name", 100, HorizontalAlignment.Left);

                Type t = entity.GetType();
                PropertyInfo[] pi = t.GetProperties();

                foreach (PropertyInfo prop in pi)
                {
                    if (prop.Name == "ClassName" || prop.Name == "ScanID" || prop.Name == "Name" || prop.Name == "Icon" || prop.Name == "NodeName")
                        continue;

                    if (prop.GetValue(entity, null).GetType().Name == "DateTime" && DateTime.MinValue == (DateTime)prop.GetValue(entity, null))
                        listItem.SubItems.Add("");
                    else
                    {
                        listItem.SubItems.Add(prop.GetValue(entity, null).ToString());
                    }

                    if (bCreateColumns == true)
                        lstEnvVars.Columns.Add(prop.Name, 100, HorizontalAlignment.Left);
                }
                lstEnvVars.Items.Add(listItem);
                bCreateColumns = false;
            }
            lstEnvVars.Columns[0].Width = -1;

            tempArray.Clear();
            tempArray = null;
        }

        void DisplayUserGroupDetails()
        {
            _logger.Info("Displaying User Group details");

            if (objDataTable == null || objDataTable["UserGroups"] == null)
            {
                SetProgressBarState(false);
                return;
            }

            ArrayList tempArray = (ArrayList)objDataTable["UserGroups"];

            if (tempArray.Count <= 0)
            {
                SetProgressBarState(false);
                return;
            }


            bool bCreateColumns = true;

            if (lstUserGroups.Columns.Count != 0)
            {
                bCreateColumns = false;
            }

            foreach (object entity in tempArray)
            {

                ListViewItem listItem = new ListViewItem();

                listItem.Text = entity.GetType().GetProperty("Name")
                    .GetValue(entity, null).ToString();
                listItem.ImageIndex = 0;

                if (bCreateColumns == true)
                    lstUserGroups.Columns.Add("Name", 100, HorizontalAlignment.Left);

                Type t = entity.GetType();
                PropertyInfo[] pi = t.GetProperties();

                foreach (PropertyInfo prop in pi)
                {
                    if (prop.Name == "ClassName" || prop.Name == "ScanID" || prop.Name == "Name" || prop.Name == "Icon" || prop.Name == "NodeName")
                        continue;

                    if (prop.GetValue(entity, null).GetType().Name == "DateTime" && DateTime.MinValue == (DateTime)prop.GetValue(entity, null))
                        listItem.SubItems.Add("");
                    else
                    {
                        listItem.SubItems.Add(prop.GetValue(entity, null).ToString());
                    }

                    if (bCreateColumns == true)
                        lstUserGroups.Columns.Add(prop.Name, 100, HorizontalAlignment.Left);
                }
                lstUserGroups.Items.Add(listItem);
                bCreateColumns = false;
            }
            lstUserGroups.Columns[0].Width = -1;

            tempArray.Clear();
            tempArray = null;
        }


        void worker_collectWmiDataComplete(object sender, RunWorkerCompletedEventArgs e)
        {
            //TODO_HIGH: Need to add threading logic for wmi data retrival
            _logger.Info("Wmi background worker task complete");

            ClearDisplayControls();
            DisplaySystemDetails();
            DisplayProcessesDetails();
            DisplaySoftwareDetails();
            DisplayServicesDetails();
            DisplayIPRoutesDetails();
            DisplayEnvVarDetails();
            DisplayUserGroupDetails();

        }

        void worker_collectWmiData(object sender, DoWorkEventArgs e)
        {
            _logger.Info("Wmi background worker start");
            objDataTable.Clear(); 

            ThreadParam tempParam = (ThreadParam)e.Argument; 
            Controller.Instance.GetWmiDataFromDB(tempParam.machineName, tempParam.dateTime, ref objDataTable);
        }

        void Instance_ScanComplete(object sender, string machineName)
        {
            _logger.Info("Scan complete");
            SetProgressBarState(false);

            List<EntDiscover>machList = Controller.Instance.UpdateFromDatabase(machineName);
            RefreshMachineList(machList);

        }

        void Instance_MachineDiscoveryComplete(object sender, EventArgs args)
        {
            _logger.Info("Machine discoveery complete");
            SetProgressBarState(false);

//TODO_NORM: Select the first machine on load
        }

        void Instance_MachineDiscoveryStart(object sender, DiscoveryDetailsArgs args)
        {
            _logger.Info("Machine discoveery start");
            SetProgressBarState(true);
        }

        void Instance_StatusMessage(object sender, string message)
        {
            SetStatusMessage(message);
        }

        void Instance_MachineFound(object sender, MachineDetailsArgs args)
        {
            RefreshMachineList(Controller.Instance.UpdateFromDatabase(args.MachineName));
        }

        private delegate void AddListBoxItemDelegate(List<EntDiscover> machineList);
        private void RefreshMachineList(List<EntDiscover> machineList)
        {
            if (this.lstMonitoredMachine.InvokeRequired)    
            {        
                // This is a worker thread so delegate the task.        
                this.lstMonitoredMachine.Invoke(new AddListBoxItemDelegate(this.RefreshMachineList), machineList);    
            }    
            else    
            {
                foreach (EntDiscover machine in machineList)
                {
                    bool bListed = false;
                    foreach (ListViewItem item in lstMonitoredMachine.Items)
                    {
                        if (item.Tag.ToString() == machine.MachineName)
                        {
                            bListed = true;
                            item.SubItems[0].Text = machine.MachineName;
                            item.SubItems[1].Text = machine.IPAddr;
                            item.SubItems[2].Text = machine.StatusMessage.Trim();

                            if (machine.Discovered == true)
                            {
                                item.ImageIndex = (int)ImageCode.MachineOk;
                            }
                            else
                            {
                                item.ImageIndex = (int)ImageCode.MachineNotOk;
                            }
                        }
                    }

                    if (bListed == false)
                    {
                        
                        string[] param = { machine.MachineName, machine.IPAddr, machine.StatusMessage.Trim() };
                        ListViewItem newItem = new ListViewItem(param);
                        newItem.Name = machine.MachineName;
                        newItem.Tag = machine.MachineName;
                        if (machine.Discovered == true)
                        {
                            newItem.ImageIndex = (int)ImageCode.MachineOk;
                        }
                        else
                        {
                            newItem.ImageIndex = (int)ImageCode.MachineNotOk;
                        }

                        lstMonitoredMachine.Items.Add(newItem);
                        newItem = null;
                    }
                }
                if (lstMonitoredMachine.SelectedItems.Count > 0)
                {
                    lblCollectionStatus.Visible = false;
                    string machineName = lstMonitoredMachine.SelectedItems[0].Text;
                    FillScanCombo(machineName);

                    if (cbScans.Items.Count > 0)
                        GetWmiData(machineName, (DateTime)cbScans.SelectedItem);
                    else
                    {
                        ClearDisplayControls();
                        lblCollectionStatus.Visible = true;
                        lblCollectionStatus.Text = "Data not collected for this machine";
                    }
                }
                if (lstMonitoredMachine.Columns.Count > 0 && lstMonitoredMachine.Items.Count > 0)
                {
                    lstMonitoredMachine.Columns[0].Width = -1;
                    lstMonitoredMachine.Columns[1].Width = -1;
                    lstMonitoredMachine.Columns[2].Width = -1;
                }

            }


            SetStatusMessage("");
        }

/*
        private void RefreshMachineList(List<EntDiscover> machineList)
        {
            this.lstMonitoredMachine.SafeControlInvoke
            (
                lstMonitoredMachine1 =>
                {

                }
            );

        }
*/

        private void MainUI_Load(object sender, EventArgs e)
        {
            List<EntDiscover> machLst = Controller.Instance.UpdateFromDatabase(null);
            RefreshMachineList(machLst);
        }

        private void addMachinesToolStripMenuItem_Click(object sender, EventArgs e)
        {
        }

        private void addComputersByDomainToolStripMenuItem_Click(object sender, EventArgs e)
        {
            FrmAddByDomain objFrm = new FrmAddByDomain();
            if ( objFrm.ShowDialog(this) == DialogResult.OK)
            {
                if (objFrm.DomainName.Equals("ALL MACHINES", StringComparison.OrdinalIgnoreCase))
                {
                    Controller.Instance.GetMachines("*"); 
                }
                else
                {
                    Controller.Instance.GetMachines(objFrm.DomainName); 
                }
            }
        }

        private void SetStatusMessage(string message)
        {
            this.statusStrip.SafeControlInvoke
            (
                statusStrip =>
                {
                    tsStatus.Text = message; 
                }
            );
        }

        private void SetProgressBarState(bool state)
        {
            this.statusStrip.SafeControlInvoke
            (
                statusStrip =>
                {
                    if ( state == true)
                    {
                        tsProgBar.Style = ProgressBarStyle.Marquee;
                        tsProgBar.MarqueeAnimationSpeed = 70;
                    }
                    else
                    {
                        tsProgBar.Style = ProgressBarStyle.Blocks;
                    }
                }
            );
        }

        private void debugViewToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if ( dbgProcess== null || dbgProcess.HasExited == true)
            {
                dbgProcess = new Process();
                dbgProcess = Process.Start("DebugWindow.exe");
            }
        }
        private void MainUI_FormClosing(object sender, FormClosingEventArgs e)
        {
            if ( dbgProcess!=null)
            {
                if (dbgProcess.HasExited == false)
                {
                    dbgProcess.Kill();
                    dbgProcess.Dispose();
                    dbgProcess = null;
                }
            }
        }

        private void scanToolStripMenuItem_Click(object sender, EventArgs e)
        {
            SetProgressBarState(true);
            ListView.CheckedListViewItemCollection machList = lstMonitoredMachine.CheckedItems;
            foreach ( ListViewItem item in machList)
            {
                Controller.Instance.ScanMachine(item.Text);
            }
        }

        /// <summary>
        /// monitored machine list item change event.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void lstMonitoredMachine_ItemSelectionChanged(object sender, ListViewItemSelectionChangedEventArgs e)
        {
            //TODO_LOW: Need to fix this logic proper list handling 
            // probably this might help: 
            // http://social.msdn.microsoft.com/forums/en-US/winforms/thread/b79ec02a-c47d-4417-bf83-9433d63ad066


            if (e.IsSelected == false)
            {
                if ( lstMonitoredMachine.SelectedItems.Count>0)
                {
                    e.Item.Selected = true;
                    lstMonitoredMachine.Select();
                    iLstUnSelect = e.ItemIndex;
                }
                else
                {
                    ClearDisplayControls();
                }
            }
            else
            {
                if (iLstUnSelect!= lstMonitoredMachine.SelectedItems[0].Index)
                {
                    lblCollectionStatus.Visible = false;
                    string machineName = lstMonitoredMachine.SelectedItems[0].Text;
                    FillScanCombo(machineName);

                    if (cbScans.Items.Count > 0)
                        GetWmiData(machineName, (DateTime)cbScans.SelectedItem);
                    else
                    {
                        ClearDisplayControls();
                        lblCollectionStatus.Visible = true;
                        lblCollectionStatus.Text = "Data not collected for this machine";
                    }
                }
            }
        }

        /// <summary>
        /// Fucntion clears all the display controls. 
        /// </summary>
        private void ClearDisplayControls()
        {

            if (lstDisplayInfo.Nodes.Count > 0)
            {
                lstDisplayInfo.Nodes.Clear();
                lstDisplayInfo.Invalidate();
            }
            if (lstProcesses.Items.Count > 0)
            {
                lstProcesses.Items.Clear();
            }
            if (lstSoftwares.Items.Count > 0)
            {
                lstSoftwares.Items.Clear();
            }
            if (lstServices.Items.Count > 0)
            {
                lstServices.Items.Clear();
            }
            if (lstIPRoutes.Items.Count > 0)
            {
                lstIPRoutes.Items.Clear();
            }
            if (lstEnvVars.Items.Count > 0)
            {
                lstEnvVars.Items.Clear();
            }
            if (lstUserGroups.Items.Count > 0)
            {
                lstUserGroups.Items.Clear();
            }


        }

        /// <summary>
        /// Function is called when a particular machine is selected from the monitored machine list.
        /// Fills the combo with the scan date information associated with the machine. 
        /// </summary>
        /// <param name="machineName"></param>
        private void FillScanCombo(string machineName)
        {
            bool bFoundData = false;
            cbScans.Items.Clear();
            cbScans.Text = "";
            foreach (EntScan scan in Controller.Instance.GetAllScans(machineName))
            {
                cbScans.Items.Add(scan.Date);
                bFoundData = true; 
            }

            if ( bFoundData == true)
                cbScans.SelectedIndex = cbScans.Items.Count - 1; 
        }

        /// <summary>
        /// Gets the wmi data from the database
        /// </summary>
        /// <param name="machineName">Name of the machine for which data is to be queried</param>
        /// <param name="scanDate">Date of the scan received from the scan drop down</param>
        private void GetWmiData(string machineName, DateTime scanDate)
        {
            ThreadParam tempParam = new ThreadParam();
            tempParam.machineName = machineName;
            tempParam.dateTime = scanDate;

            SetProgressBarState(true); 

            if ( worker.IsBusy == false)
                worker.RunWorkerAsync(tempParam); 
        }
                
        /// <summary>
        /// Function splits input string on CamelCase basis.
        /// </summary>
        /// <param name="inputCamelCaseString">String that will be split</param>
        /// <returns></returns>
        private string SplitCamelCase(string inputCamelCaseString)
        {
            string sTemp=Regex.Replace(inputCamelCaseString, "([A-Z][a-z])", " $1",RegexOptions.Compiled).Trim();
            return Regex.Replace(sTemp, "([A-Z][A-Z])", " $1", RegexOptions.Compiled).Trim();
        }

        /// <summary>
        /// Callback is called when the state of the expand check box changes.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void cbListExpand_CheckedChanged(object sender, EventArgs e)
        {
            if (lstDisplayInfo.Nodes.Count > 0)
            {
                if (cbListExpand.Checked == true)
                {
                    lstDisplayInfo.ExpandAll();
                    lstDisplayInfo.Invalidate();
                }
                else
                {
                    lstDisplayInfo.CollapseAll();
                    lstDisplayInfo.Invalidate();
                }
            }
        }

        /// <summary>
        /// Callback is called when the add computer by hostname menu item is clicked.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void addComputersByHostnameToolStripMenuItem_Click(object sender, EventArgs e)
        {
            FrmAddByHostName objFrm = new FrmAddByHostName();
            if (objFrm.ShowDialog(this) == DialogResult.OK)
            {
                Controller.Instance.GetMachinesByHostName(objFrm.HostName); 

            }
        }

        /// <summary>
        /// Callback is called when the about menu item is clicked.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
        {
            AboutBox objAbout = new AboutBox();
            objAbout.ShowDialog();
        }

        /// <summary>
        /// Callback is called when user right clicks and selects delete from context menu.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void deleteMachineToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (MessageBox.Show("Are you sure you want to remove this machine from monitoring system", "Delete machine", MessageBoxButtons.YesNo) == DialogResult.Yes)
            {
                ClearDisplayControls();
                cbScans.Items.Clear();
                cbScans.Text = "";
                SetProgressBarState(true);
                //ListView.Che 
                ListView.CheckedListViewItemCollection machList = lstMonitoredMachine.CheckedItems; 
                foreach (ListViewItem item in machList)
                {
                    Controller.Instance.DeleteMachine(item.Text);
                    lstMonitoredMachine.Items.Clear();
                }
                Controller.Instance.UpdateMachineList();
                SetProgressBarState(false);
            }
        }

        /// <summary>
        /// Callback is called lstMonitoredMachine context menu is displayed.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void contextMenuStrip1_Opening(object sender, CancelEventArgs e)
        {
            deleteMachineToolStripMenuItem.Enabled = true;
            scanToolStripMenuItem.Enabled = true;

            if ( lstMonitoredMachine.SelectedItems.Count <= 0)
            {
                e.Cancel = true;
            }
            if ( lstMonitoredMachine.CheckedItems.Count <= 0)
            {
                scanToolStripMenuItem.Enabled = false;
                deleteMachineToolStripMenuItem.Enabled = false;
            }
        }

        /// <summary>
        /// Scans all the machines in the monitored machine list.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void scanAllComputerToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if ( lstMonitoredMachine.Items.Count > 0 ) 
            {
                SetProgressBarState(true);
                ListView.ListViewItemCollection machList = lstMonitoredMachine.Items; 
                foreach (ListViewItem item in machList)
                {
                    Controller.Instance.ScanMachine(item.Text);
                }
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void deleteCurScanToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void systemReportToolStripMenuItem_Click(object sender, EventArgs e)
        {
            FrmReport objFrmReport = new FrmReport();
            if (objFrmReport.ShowDialog(this) == DialogResult.Cancel)
            {

            }

        }

        private void cbScans_SelectedIndexChanged(object sender, EventArgs e)
        {
            if ( lstMonitoredMachine.SelectedItems.Count >= 0 )
            {
                if (cbScans.Items.Count > 0)
                    GetWmiData(lstMonitoredMachine.SelectedItems[0].Text, (DateTime)cbScans.SelectedItem);
            }
        }


        /// <summary>
        /// Callback is called when the add credential configuration menu item is clicked.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>

        private void credentialsConfigToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            FrmCredentials objFrmCredentials = new FrmCredentials();
            if (objFrmCredentials.ShowDialog(this) == DialogResult.Cancel)
            {
                if (objFrmCredentials.UpdatedList.Count > 0)
                {
                    Controller.Instance.SetCredentials(objFrmCredentials.UpdatedList);
                }
            }
        }

        private void credentialsMapToolStripMenuItem_Click(object sender, EventArgs e)
        {
            FrmUserMapping objFrmUserMapping = new FrmUserMapping();
            if (objFrmUserMapping.ShowDialog(this) == DialogResult.Cancel)
            {

            }

        }

        private void viewSystemInformationToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }

        private void dNSLookupToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }
        /*
        private void mapCredentialsToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }
*/

    }

    /// <summary>
    /// Thread param for the background worker thread. 
    /// </summary>
    class ThreadParam 
    {
        public string machineName;
        public DateTime dateTime; 
    }
}
